package com.incar.chuxing.application;

import android.app.Application;
import android.app.Notification;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.support.multidex.MultiDex;
import android.util.Log;
import android.view.View;

import com.alibaba.sdk.android.media.utils.Md5Utils;
import com.baidu.mapapi.SDKInitializer;
import com.github.nkzawa.emitter.Emitter;
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.incar.chuxing.BuildConfig;
import com.incar.chuxing.R;
import com.incar.chuxing.api.UrlContainer;
import com.incar.chuxing.bean.ForeBackGroundEvent;
import com.incar.chuxing.utils.CarDamagePicLoad;
import com.incar.chuxing.utils.FileLogUtils;
import com.incar.chuxing.utils.ForegroundCallbacks;
import com.incar.chuxing.utils.LoadSirCallback.EmptyCallback;
import com.incar.chuxing.utils.LoadSirCallback.LoadingWithContentCallback;
import com.incar.chuxing.utils.LoadSirCallback.NetErrorCallback;
import com.incar.chuxing.utils.LoadSirCallback.ServerErrorCallback;
import com.incar.chuxing.utils.Logger;
import com.incar.chuxing.utils.RxBus;
import com.incar.chuxing.utils.SPKey;
import com.incar.chuxing.utils.SPUtils;
import com.incar.chuxing.utils.VerControlUtils;
import com.incar.chuxing.utils.ble.ViseBluetooth;
import com.incar.chuxing.utils.bos.UploadFile;
import com.incar.chuxing.utils.wangyiqiyu.GlideImageLoader;
import com.inuker.bluetooth.library.ClientManager;
import com.kingja.loadsir.core.LoadSir;
import com.qiyukf.unicorn.api.OnBotEventListener;
import com.qiyukf.unicorn.api.UICustomization;
import com.qiyukf.unicorn.api.Unicorn;
import com.qiyukf.unicorn.api.YSFOptions;
import com.readystatesoftware.chuck.ChuckInterceptor;
import com.tencent.bugly.Bugly;
import com.tencent.bugly.beta.Beta;
import com.tencent.bugly.beta.UpgradeInfo;
import com.tencent.bugly.beta.ui.UILifecycleListener;
import com.umeng.analytics.MobclickAgent;
import com.umeng.commonsdk.UMConfigure;
import com.umeng.message.IUmengRegisterCallback;
import com.umeng.message.PushAgent;
import com.umeng.message.UmengMessageHandler;
import com.umeng.message.UmengNotificationClickHandler;
import com.umeng.message.entity.UMessage;
import com.umeng.socialize.Config;
import com.umeng.socialize.PlatformConfig;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.net.URISyntaxException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static android.os.Build.VERSION.SDK_INT;


/**
 * Created by Michael Pi on 2016/10/9.
 */
public class MyApplication extends Application {

    public YSFOptions options;

    {
        PlatformConfig.setWeixin("wx11168c360e45dc15", "1a8ec8cf30865b6b83559baa6662aae9");
        PlatformConfig.setQQZone("1106463293", "j0Wj7XRDQHcoUeKV");
        Config.DEBUG = true;
    }

    private String sign;
    private Context mContext = this;
    private static MyApplication instance;
    public int count = 0;
    private boolean firstLoadConfig = true;
    public static ChuckInterceptor chuckInterceptor;

    public static MyApplication getInstance() {
        return instance;
    }

    public Socket mSocket;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        SDKInitializer.initialize(mContext); //百度地图初始化
        initBugly();
        initUmeng();
        initLoadSir();
        ViseBluetooth.getInstance().init(this);
        ClientManager.initClient(this);
        FileLogUtils.init(this);
        registerLifeCycle();
        // you can also use "new FrescoImageLoader()" or "new PicassoImageLoader()"//网易七鱼
        Unicorn.init(this, "6206d6a7abc4dfb447035896d3d2953b", ysfOptions(), new GlideImageLoader(this));
        Unicorn.toggleNotification(false);
        initConfigMode();
        if (BuildConfig.DEBUG) {
            chuckInterceptor = new ChuckInterceptor(mContext);
        }
        initSocketIO();
        initCarDamagePic();
    }


    private void initSocketIO() {
        Emitter.Listener onNewMessage = new Emitter.Listener() {
            @Override
            public void call(final Object... args) {
                new Handler(getMainLooper()).post(() -> {
                    //JSONObject data = (JSONObject) args[0];

                });
            }
        };
        try {
            IO.Options options = new IO.Options();
            options.path = "/push";
            options.reconnection = true;
            options.reconnectionAttempts = 100;
            options.query = "userId=123&phoneNum=18515928795&appId=0&token=123&phoneType=Android";
            mSocket = IO.socket("https://socket-dev.mydadao.com/", options);
            mSocket.on(Socket.EVENT_CONNECT, onNewMessage);
            mSocket.connect();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

    }

    private void initCarDamagePic() {
        new CarDamagePicLoad().load(this);
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }

    private void registerLifeCycle() {
        ForegroundCallbacks.get(this).addListener(new ForegroundCallbacks.Listener() {
            @Override
            public void onBecameForeground() {
                Log.d("foregroundcallbacks", "到前台了");
                if (firstLoadConfig) {
                    firstLoadConfig = false;
                    GetAppConfig.getInstance(mContext).getConfig(null);
                }
                RxBus.getInstance().post(new ForeBackGroundEvent(true));
            }

            @Override
            public void onBecameBackground() {
                RxBus.getInstance().post(new ForeBackGroundEvent(false));
                Log.d("foregroundcallbacks", "到后台了");
            }
        });
    }


    private YSFOptions ysfOptions() {
        options = new YSFOptions();
        options.uiCustomization = new UICustomization();
        options.uiCustomization.hideAudio = true;
        options.uiCustomization.leftAvatar = "android.resource://" + mContext.getPackageName() + "/" + R.mipmap.ic_launcher;
        options.onBotEventListener = new OnBotEventListener() {
            @Override
            public boolean onUrlClick(Context context, String url) {
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                context.startActivity(intent);
                return true;
            }
        };
        return options;
    }

    private void initLoadSir() {

        LoadSir.beginBuilder()
                .addCallback(new NetErrorCallback())
                .addCallback(new EmptyCallback())
                .addCallback(new LoadingWithContentCallback())
                .addCallback(new ServerErrorCallback())
                .commit();
    }

    private void initBugly() {
        Beta.canShowApkInfo = false;//bugly更新应用设置
        Beta.upgradeDialogLayoutId = R.layout.dialog_layout_update;
        Beta.tipsDialogLayoutId = R.layout.dialog_layout_update_netip;
        Beta.strNetworkTipsTitle = "提醒";
        Beta.strUpgradeDialogCancelBtn = "取消";
        Beta.strUpgradeDialogUpgradeBtn = "升级";
        Beta.upgradeDialogLifecycleListener = new UILifecycleListener<UpgradeInfo>() {
            @Override
            public void onCreate(Context context, View view, UpgradeInfo upgradeInfo) {
                // 注：可通过这个回调方式获取布局的控件，如果设置了id，可通过findViewById方式获取，如果设置了tag，可以通过findViewWithTag，具体参考下面例子:
                // 通过tag方式获取控件，并更改布局内容
                View btn_line = view.findViewById(R.id.btn_line);
                if (upgradeInfo.upgradeType == 2) {
                    btn_line.setVisibility(View.GONE);
                }
            }

            @Override
            public void onStart(Context context, View view, UpgradeInfo upgradeInfo) {

            }

            @Override
            public void onResume(Context context, View view, UpgradeInfo upgradeInfo) {

            }

            @Override
            public void onPause(Context context, View view, UpgradeInfo upgradeInfo) {

            }

            @Override
            public void onStop(Context context, View view, UpgradeInfo upgradeInfo) {

            }

            @Override
            public void onDestroy(Context context, View view, UpgradeInfo upgradeInfo) {

            }

        };
        Bugly.init(mContext, "79f2acc4ff", false);//bugly初始化
    }

    private void initUmeng() {
        UMConfigure.init(mContext, UMConfigure.DEVICE_TYPE_PHONE, "c1613f493f959ca9eed47bb465e9f078");
        MobclickAgent.setScenarioType(mContext, MobclickAgent.EScenarioType.E_UM_NORMAL);
        MobclickAgent.openActivityDurationTrack(false);
        //接收友盟消息
        PushAgent mPushAgent = PushAgent.getInstance(mContext);
        //注册推送服务，每次调用register方法都会回调该接口
        mPushAgent.register(new IUmengRegisterCallback() {
            @Override
            public void onSuccess(String deviceToken) {
                SPUtils.getInstance(mContext).putStringValue(SPKey.DEVICE_TOKEN, deviceToken);
                Logger.i("deviceToken", deviceToken + "");
            }

            @Override
            public void onFailure(String s, String s1) {
            }
        });


        UmengMessageHandler messageHandler = new UmengMessageHandler() {
            @Override
            public Notification getNotification(final Context context, final UMessage msg) {
                new Handler(getMainLooper()).post(() -> {
                });
                return super.getNotification(context, msg);
            }

            @Override
            public void dealWithCustomMessage(Context context, UMessage uMessage) {
                new Handler(getMainLooper()).post(() -> {
                    if (uMessage.custom.contains("$日志new$")) {
                        Logger.i("日志", "接收到上传新日志的推送消息");
                        UploadFile.getInstance().uploadPicToBos(mContext, "logs.txt");
                    } else if (uMessage.custom.contains("$日志old$")) {
                        Logger.i("日志", "接收到上传旧日志的推送消息");
                        UploadFile.getInstance().uploadPicToBos(mContext, "lastLogs.txt");
                    }
                });
            }

            @Override
            public void dealWithNotificationMessage(Context context, UMessage uMessage) {
                super.dealWithNotificationMessage(context, uMessage);
            }
        };
        mPushAgent.setMessageHandler(messageHandler);


        //接收友盟通知，需点击通知，即可接收自定义参数
        UmengNotificationClickHandler notificationClickHandler = new UmengNotificationClickHandler() {
            @Override
            public void launchApp(Context context, UMessage uMessage) {
                super.launchApp(context, uMessage);
            }

            @Override
            public void dealWithCustomAction(Context context, UMessage uMessage) {
            }
        };
        mPushAgent.setNotificationClickHandler(notificationClickHandler);
    }


    private void initConfigMode() {
        Map<String, String> apiMap = UrlContainer.Request.h5UrlMap;
        if (BuildConfig.DEBUG) {
            switch (SPUtils.getInstance(mContext).getIntValue("$s_urlMode")) {
                case 1://Dev
                    apiMap = getApiMap(apiMap, "defaultApi/devApi.json");
                    UrlContainer.Request.BASE_CONFIG_URL = UrlContainer.Request.BASE_CONFIG_TEST_URL;
                    break;
                case 0://默认test
                case 2://Test
                    apiMap = getApiMap(apiMap, "defaultApi/testApi.json");
                    UrlContainer.Request.BASE_CONFIG_URL = UrlContainer.Request.BASE_CONFIG_TEST_URL;
                    break;
                case 4://DEV2
                    apiMap = getApiMap(apiMap, "defaultApi/dev2Api.json");
                    UrlContainer.Request.BASE_CONFIG_URL = UrlContainer.Request.BASE_CONFIG_TEST_URL;
                    break;
                case 5://自定义IP
                    apiMap = getApiMap(apiMap, "defaultApi/testApi.json");
                    UrlContainer.Request.BASE_CONFIG_URL = UrlContainer.Request.BASE_CONFIG_TEST_URL;
                    break;
                case 6://Pre
                    apiMap = getApiMap(apiMap, "defaultApi/preApi.json");
                    UrlContainer.Request.BASE_CONFIG_URL = UrlContainer.Request.BASE_CONFIG_PRE_URL;
                    break;
                case 3://prod模式使用默认设置
                    apiMap = getApiMap(apiMap, "defaultApi/proApi.json");
                    break;
            }
            UrlContainer.Request.BASE_GATE_URL = apiMap.get(UrlContainer.Request.apiServerNewV2);
            setImageUrl(apiMap.get("imgPrefixUrl"));
        } else {
            apiMap = getApiMap(apiMap, "defaultApi/proApi.json");
            setImageUrl(apiMap.get("imgPrefixUrl"));
            //默认是release地址，release版不再设置BASE_GATE_URL、BASE_CONFIG_URL
        }
    }

    private Map<String, String> getApiMap(Map<String, String> apiMap, String fileName) {
        //将json数据变成字符串
        StringBuilder stringBuilder = new StringBuilder();
        try {
            //获取assets资源管理器
            AssetManager assetManager = getAssets();
            //通过管理器打开文件并读取
            BufferedReader bf = new BufferedReader(new InputStreamReader(assetManager.open(fileName)));
            String line;
            while ((line = bf.readLine()) != null) {
                stringBuilder.append(line);
            }
            JSONObject jsonObject = new JSONObject(stringBuilder.toString());
            Type typeApi = new TypeToken<Map<String, String>>() {
            }.getType();


            apiMap.putAll(new Gson().fromJson(jsonObject.getJSONObject("server_url").toString(), typeApi));
            apiMap.putAll(new Gson().fromJson(jsonObject.getJSONObject("h5_url").toString(), typeApi));
            apiMap.put("imgPrefixUrl", jsonObject.getString("imgPrefixUrl"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return apiMap;
    }


    public String getUid() {
        return SPUtils.getInstance(mContext).getStringValue(SPKey.USER_ID);
    }

    public void setUid(String uid) {
        SPUtils.getInstance(mContext).putStringValue(SPKey.USER_ID, uid);
    }

    public String getToken() {
        return SPUtils.getInstance(mContext).getStringValue(SPKey.USER_TOKEN);
    }

    public void setToken(String token) {
        SPUtils.getInstance(mContext).putStringValue(SPKey.USER_TOKEN, token);
    }


    public String getHeaderToken() {
        return SPUtils.getInstance(mContext).getStringValue(SPKey.USER_HEADER_TOKEN);

    }

    public void setHeaderToken(String headerToken) {
        SPUtils.getInstance(mContext).putStringValue(SPKey.USER_HEADER_TOKEN, headerToken);
    }


    public String getAppVersion() {
        return VerControlUtils.getInstance(mContext).getVersionName();
    }

    public String getImageUrl() {
        return SPUtils.getInstance(mContext).getStringValue(SPKey.IMAGE_URL);
    }

    public void setImageUrl(String imageUrl) {
        SPUtils.getInstance(mContext).putStringValue(SPKey.IMAGE_URL, imageUrl);
    }


    //sign&timestamp
    public String getTimestamp() {
        String timestamp = new Date().getTime() + "";
        try {
            sign = Md5Utils.getMD5String(timestamp + "incar1"); //时间戳+incar+1(平台)

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return timestamp;
    }

    public String getSign() {
        return sign;
    }

    public String getAreaCode() {
        return SPUtils.getInstance(mContext).getStringValue(SPKey.AREA_CODE);
    }

    public void setAreaCode(String areaCode) {
        if (areaCode != null) {
            SPUtils.getInstance(mContext).putStringValue(SPKey.AREA_CODE, areaCode);
        }
    }

    public String getAdCode() {
        return SPUtils.getInstance(mContext).getStringValue(SPKey.AD_CODE);
    }

    public void setAdCode(String adCode) {
        if (adCode != null) {
            SPUtils.getInstance(getApplicationContext()).putStringValue(SPKey.AD_CODE, adCode);
        }
    }

    public void setCurPosition(String latitude, String longitude) {
        if (!"".equals(latitude) && latitude != null) {
            SPUtils.getInstance(getApplicationContext()).putStringValue(SPKey.CUR_POSITION, latitude + "," + longitude);
        }
    }

    public String[] getCurPosition() {
        String savedCurPosition = SPUtils.getInstance(mContext).getStringValue(SPKey.CUR_POSITION);
        if (savedCurPosition != null) {
            return savedCurPosition.split(",");
        }
        return null;
    }

    private Map<String, String> requestFieldMap;

    public Map<String, String> getRequestFieldMap() {
        if (requestFieldMap == null) {
            requestFieldMap = new HashMap<>();
        }
        String uid = getUid();
        if (uid != null) {
            requestFieldMap.put("userId", uid);
            requestFieldMap.put("uid", uid);
            requestFieldMap.put("token", getToken());
        } else {
            requestFieldMap.remove("userId");
            requestFieldMap.remove("uid");
            requestFieldMap.remove("token");
        }


        String areaCode = getAreaCode();
        if (areaCode != null) {
            requestFieldMap.put("areaCode", areaCode);
        }
        String adCode = getAdCode();
        if (getAdCode() != null) {
            requestFieldMap.put("adCode", adCode);
        }
        String[] curPosition = getCurPosition();
        if (curPosition != null && null != curPosition[0]) {
            requestFieldMap.put("latitude", curPosition[0]);
            requestFieldMap.put("longitude", curPosition[1]);
        }

        requestFieldMap.put("timestamp", getTimestamp());
        requestFieldMap.put("sign", getSign());
        requestFieldMap.put("appVersion", getAppVersion());
        requestFieldMap.put("phoneSysVersion", SDK_INT + " ");
        requestFieldMap.put("device_brand", Build.MANUFACTURER + " ");
        requestFieldMap.put("phoneModel", Build.MODEL + " ");
        requestFieldMap.put("plateForm", "1");
        requestFieldMap.put("platform", "1");
        if (SPUtils.getInstance(mContext).getStringValue(SPKey.DEVICE_TOKEN) != null &&
                !(SPUtils.getInstance(mContext).getStringValue(SPKey.DEVICE_TOKEN) + "").equals("null")) {
            requestFieldMap.put("device", SPUtils.getInstance(mContext).getStringValue(SPKey.DEVICE_TOKEN) + "");
        }
        return requestFieldMap;
    }


    private Map<String, String> requestHeaderMap;

    public Map<String, String> getRequestHeaderMap() {
        if (requestHeaderMap == null) {
            requestHeaderMap = new HashMap<>();
        }
        requestHeaderMap.put("x-incar-token", getHeaderToken());
        requestHeaderMap.put("x-token", getHeaderToken());
        requestHeaderMap.put("x-incar-app-id", "f8994b56b9ff4c4ca60a37dd0ec0cb87");

        String[] curPosition = getCurPosition();

        if (curPosition != null && null != curPosition[0]) {
            requestHeaderMap.put("xlatitude", curPosition[0]);
            requestHeaderMap.put("xlongitude", curPosition[1]);
        }
        requestHeaderMap.put("x-incar-request-moudle", "incar");
        requestHeaderMap.put("x-incar-version", getAppVersion());
        requestHeaderMap.put("x-incar-timestamps", getTimestamp());
        if (BuildConfig.DEBUG) {
            requestHeaderMap.put("env", "debug");
        }


        return requestHeaderMap;
    }


    private HashMap<String, String> webCookieMap;

    public HashMap<String, String> getCookieMap() {
        if (webCookieMap == null) {
            webCookieMap = new HashMap<>();
        }

        webCookieMap.putAll(getRequestFieldMap());
        webCookieMap.putAll(getRequestHeaderMap());

        webCookieMap.put("imgUrl", getImageUrl());
        webCookieMap.put("openid", SPUtils.getInstance(mContext).getStringValue(SPKey.OPEN_ID));
        return webCookieMap;
    }

}
